/*
 * 
 * ....................................................................
 * ...######..#####.....##....####..#####..####..#####..######....##...
 * .....##....##..#....###...##.....##.....##....##..#....##.....###...
 * .....##....####....#.##....##....####...####..####.....##....#.##...
 * .....##....##.#...#####.....##...##.....##....##.#.....##...#####...
 * .....##....##..#.#...##..####....##.....####..##..#....##..#...##...
 * ....................................................................
 */

package ua.trasferta.common.collections;

import java.util.Comparator;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import ua.trasferta.common.annotations.createBy;
import static ua.trasferta.common.team.TeamMember.*;
import static ua.trasferta.common.pattern.Pattern.*;

/**
 * Java class with static utility methods pertaining to {@link Map} instances.
 * 
 * @NOTE this class inspired by <b>google-collections</b> and Joshua Bloch book
 *       for effective programming.
 * @SEE http://code.google.com/p/google-collections/
 * @SEE {@link Lists}.
 * @SEE {@link Sets}.
 * @SEE http://code.google.com/p/trasferta/
 * @author Anton Podviaznikov
 */
@createBy(authors = ANTON_PODVIAZNIKOV)
public final class Maps
{
	/**
	 * Private constructor.
	 */
	private Maps()
	{
		// hidden constructor.
	}

	/**
	 * If you don't want be confused {@link #FACTORY} pattern should be used.
	 * 
	 * @return a new, empty {@code HashMap}.
	 */
	public static <K, V> HashMap<K, V> newHashMap()
	{
		return new HashMap<K, V>();
	}

	/**
	 * If you don't want be confused {@link #FACTORY} pattern should be used.
	 * 
	 * @param expectedSize - size of the {@code HashMap}.
	 * @return a new, empty {@code HashMap}.
	 */
	public static <K, V> HashMap<K, V> newHashMapWithExpectedSize(int expectedSize)
	{
		return new HashMap<K, V>(expectedSize);
	}

	/**
	 * If you don't want be confused {@link #FACTORY} pattern should be used.
	 * 
	 * @param map - map from which new {@code HashMap} will be get.
	 * @return a new, empty {@code HashMap}.
	 */
	public static <K, V> HashMap<K, V> newHashMap(Map<? extends K, ? extends V> map)
	{
		return new HashMap<K, V>(map);
	}

	/**
	 * If you don't want be confused {@link #FACTORY} pattern should be used.
	 * 
	 * @return a new, empty {@code LinkedHashMap}.
	 */
	public static <K, V> LinkedHashMap<K, V> newLinkedHashMap()
	{
		return new LinkedHashMap<K, V>();
	}

	/**
	 * If you don't want be confused {@link #FACTORY} pattern should be used.
	 * 
	 * @param expectedSize - size of the {@code LinkedHashMap}.
	 * @return a new, empty {@code LinkedHashMap}.
	 */
	public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(Map<? extends K, ? extends V> map)
	{
		return new LinkedHashMap<K, V>(map);
	}

	/**
	 * If you don't want be confused {@link #FACTORY} pattern should be used.
	 * 
	 * @return a new, empty {@code TreeMap}.
	 */
	public static <K extends Comparable<?>, V> TreeMap<K, V> newTreeMap()
	{
		return new TreeMap<K, V>();
	}

	/**
	 * If you don't want be confused {@link #FACTORY} pattern should be used.
	 * 
	 * @param map - map from which new {@code TreeMap} will be get.
	 * @return a new, empty {@code TreeMap}.
	 */
	public static <K, V> TreeMap<K, V> newTreeMap(SortedMap<K, ? extends V> map)
	{
		return new TreeMap<K, V>(map);
	}

	/**
	 * If you don't want be confused {@link #FACTORY} pattern should be used.
	 * 
	 * @param comparator - the comparator to sort the keys with.
	 * @return a new, empty {@code TreeMap}.
	 */
	public static <C, K extends C, V> TreeMap<K, V> newTreeMap(Comparator<C> comparator)
	{
		return new TreeMap<K, V>(comparator);
	}

	/**
	 * If you don't want be confused {@link #FACTORY} pattern should be used.
	 * 
	 * @return a new, empty {@code IdentityHashMap}.
	 */
	public static <K, V> IdentityHashMap<K, V> newIdentityHashMap()
	{
		return new IdentityHashMap<K, V>();
	}
}